import { Prisma, PrismaClient } from '@/generated/prisma/client';

export abstract class AbstractSeeder {
  abstract readonly name: string;
  abstract readonly data: any;

  async run(client: PrismaClient): Promise<void> {
    try {
      await this.before?.(client);
      await client.$transaction(async tx => this.exec(tx as Prisma.TransactionClient), {
        timeout: 30_000,
      });
      console.log(`✅ ${ this.name } seeded`);
    } catch (e) {
      console.error(`❌ ${ this.name } seed failed`, e);
      throw e;
    } finally {
      await this.after?.(client);
    }
  }

  protected abstract exec(tx: Prisma.TransactionClient): Promise<void>;

  /* 钩子 */
  protected before?(client: PrismaClient): Promise<void>;

  protected after?(client: PrismaClient): Promise<void>;
}
